import { Dimension } from '../../engine/common/dimension';
import { Vector } from '../../engine/common/vector';
import { IWorld } from '../../engine/ecs/common/world.interface';
import { ColliderComponent } from '../../engine/ecs/components/collider.component';
import { ImageRendererComponent } from '../../engine/ecs/components/image-renderer.component';
import { LocationComponent } from '../../engine/ecs/components/location.component';
import { MovementComponent } from '../../engine/ecs/components/movement.component';
import { Entity } from '../../engine/ecs/entities/entity';
import { BulletComponent } from '../components/bullet.component';

export interface IBulletCreationConfig {
  location: Vector;
  image: HTMLImageElement;
  movementDirection?: Vector;
  movementSpeed?: number;
}

export class BulletFactory {
  static create(world: IWorld, config: IBulletCreationConfig): Entity {
    const fullConfig = BulletFactory.parseConfig(config);
    const { location, image, movementDirection, movementSpeed } = fullConfig;

    const bullet = new Entity('Bullet');

    world.addEntity(bullet);
    world.attachComponentToEntity(LocationComponent, new LocationComponent(location), bullet);
    world.attachComponentToEntity(MovementComponent, new MovementComponent(movementDirection, movementSpeed), bullet);
    world.attachComponentToEntity(
      ColliderComponent,
      new ColliderComponent([{ relativeLocation: new Vector(4, 2), dimension: new Dimension(3, 6) }]),
      bullet
    );
    world.attachComponentToEntity(
      ImageRendererComponent,
      new ImageRendererComponent(image, new Dimension(10, 10)),
      bullet
    );
    world.attachComponentToEntity(BulletComponent, new BulletComponent(), bullet);

    return bullet;
  }

  static parseConfig(config: IBulletCreationConfig): Required<IBulletCreationConfig> {
    const { location, image, movementDirection, movementSpeed } = config;

    return {
      location,
      image,
      movementDirection: movementDirection ?? new Vector(0, 0),
      movementSpeed: movementSpeed ?? 150,
    };
  }
}
